home *** CD-ROM | disk | FTP | other *** search
- /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Copyright (C) 1994, by WATCOM International Inc. All rights %
- % reserved. No part of this software may be reproduced or %
- % used in any form or by any means - graphic, electronic or %
- % mechanical, including photocopying, recording, taping or %
- % information storage and retrieval systems - except with the %
- % written permission of WATCOM International Inc. %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- */
-
- #ifndef _WARRAY_HPP_INCLUDED
- #define _WARRAY_HPP_INCLUDED
- #pragma once
-
- #ifndef _WNO_PRAGMA_PUSH
- #pragma pack(push,8);
- #pragma enum int;
- #endif
-
- #ifndef _WOBJECT_HPP_INCLUDED
- # include "wobject.hpp"
- #endif
- #ifndef _WDEBUG_HPP_INCLUDED
- # include "wdebug.hpp"
- #endif
- #ifndef _WREFOBJ_HPP_INCLUDED
- # include "wrefobj.hpp"
- #endif
-
- /*************************************************************************
- *
- * WArrayReference
- *
- *************************************************************************/
-
- template <class T>
- class WCMCLASS WArrayReference : public WReferenceObject {
-
- /**********************************************************
- * Constructors and Destructors
- *********************************************************/
-
- // This class is meant to be used as a reference class, with
- // objects allocated via new. As such we don't allow
- // copies to be made except via the MakeCopy method. New
- // objects are allocated via the static function Allocate.
-
- private:
- WArrayReference( const WArrayReference & ar );
- WArrayReference & operator=( const WArrayReference & ar );
-
- protected:
- WArrayReference( size_t count );
-
- public:
- ~WArrayReference();
-
- /**********************************************************
- * Properties
- *********************************************************/
-
- // Count
-
- int GetCount() const { return _count; }
- WBool SetCount( int count );
-
- // Data
-
- T * GetData() const { return _objs; }
-
- // RealCount
-
- int GetRealCount() const;
-
- /**********************************************************
- * Methods
- *********************************************************/
-
- // Allocate
- //
- // Allocates a new object.
-
- static WArrayReference *Allocate( size_t count );
-
- // MakeCopy
- //
- // Creates a new memory object based on the current
- // one, copying the data.
-
- WArrayReference *MakeCopy( WInt newCount=-1 );
-
- /**********************************************************
- * Private
- *********************************************************/
-
- private:
-
- T * _objs;
- int _count;
- int _realCount;
- };
-
- #if defined( _DEBUG ) && !defined( new )
- #define _UNINCLUDE_NEW
- #include "wnew.hpp"
- #endif
-
- template<class T> WArrayReference<T>::WArrayReference( size_t count ) {
- _count = count;
- _realCount = count;
- _objs = NULL;
-
- if( count > 0 ) {
- _objs = new T[ count ];
- }
- }
-
- template<class T> WArrayReference<T>::~WArrayReference() {
- delete [] _objs;
-
- _objs = NULL;
- _count = 0;
- _realCount = 0;
- }
-
- template<class T> int WArrayReference<T>::GetRealCount() const {
- return _realCount;
- }
-
- template<class T> WBool WArrayReference<T>::SetCount( int count ) {
- WASSERT( count <= _realCount && count >= 0 );
- _count = count;
- return TRUE;
- }
-
- template<class T> static WArrayReference<T> * WArrayReference<T>::Allocate( size_t count ){
- WArrayReference * ref;
- ref = new WArrayReference<T>( count );
- if( ref != NULL ) {
- ref->Reference();
- return ref;
- }
- return NULL;
- }
-
- template<class T> WArrayReference<T>* WArrayReference<T>::MakeCopy( WInt newCount ){
- WArrayReference * ref;
- WInt desiredCount = newCount;
-
- if( newCount < 0 ) {
- newCount = _realCount;
- }
- ref = new WArrayReference<T>( newCount );
- WASSERT( ref != NULL );
- if( ref != NULL ){
- ref->Reference();
- if( _realCount != 0 ) {
- T * oldData;
- T * newData;
-
- if( _realCount < newCount ) {
- newCount = _realCount;
- }
- oldData = GetData();
- newData = ref->GetData();
- for( int i = 0; i < newCount; i++ ) {
- newData[i] = oldData[i];
- }
- }
- if( desiredCount < 0 ) {
- ref->_count = _count;
- } else {
- ref->_count = desiredCount;
- }
- }
- return ref;
- }
-
- /*************************************************************************
- *
- * WArray
- *
- *************************************************************************/
-
-
- template<class T>
- class WCMCLASS WArray {
-
- public:
-
- /**********************************************************
- * Constructors and Destructors
- *********************************************************/
-
- WArray();
- WArray( const T & t );
- WArray( const WArray & array );
-
- ~WArray();
-
- /**********************************************************
- * Properties
- *********************************************************/
-
- // Count
- //
- // Returns the count of items in the array.
-
- inline WInt GetCount() const;
- WBool SetCount( WInt count );
-
- // Size
- //
- // Returns the size (max # of items) of the array.
-
- WInt GetSize() const;
-
- /**********************************************************
- * Operators
- *********************************************************/
-
- inline const T & operator[]( int index ) const;
- T & operator[]( int index );
-
- inline operator const T &() const;
- operator T &();
-
- WArray & operator=( const T & t );
- WArray & operator=( const WArray & array );
-
- /**********************************************************
- * Methods
- *********************************************************/
-
- // Lock
- //
- // Lock the array for direct manipulation, possibly growing
- // it at the same time. Ensures that no one else is
- // referencing the array.
-
- T* Lock( WInt count=-1 );
-
- // Unlock
- //
- // Unlock the array after direct manipulation.
-
- void Unlock();
-
- /**********************************************************
- * Other
- *********************************************************/
-
- WInt GetRealCount() const;
-
- static const T & GetOutOfBoundsValue();
- static T & GetDummyValue();
-
- /**********************************************************
- * Data Members
- *********************************************************/
-
- protected:
-
- WArrayReference< T > *_arrRef;
- };
-
- template<class T> static const T & WArray<T>::GetOutOfBoundsValue(){
- static T _outOfBoundsValue;
- return _outOfBoundsValue;
- }
-
- template<class T> static T & WArray<T>::GetDummyValue(){
- static T _dummyValue;
- return _dummyValue;
- }
-
- template<class T> WArray<T>::WArray(){
- _arrRef = WArrayReference<T>::Allocate( 0 );
- WASSERT( _arrRef != NULL );
- }
-
- template<class T> WArray<T>::WArray( const T & t ) {
- _arrRef = WArrayReference<T>::Allocate( 1 );
- WASSERT( _arrRef != NULL );
- if( _arrRef ) _arrRef->GetData()[0] = t;
- }
-
- template<class T> WArray<T>::WArray( const WArray<T> & array ) {
- _arrRef = array._arrRef;
- WASSERT( _arrRef != NULL );
- if( _arrRef ) _arrRef->Reference();
- }
-
- template<class T> WArray<T>::~WArray() {
- WASSERT( _arrRef != NULL );
- _arrRef->Unreference();
- }
-
- template<class T> WBool WArray<T>::SetCount( WInt count ) {
- WASSERT( _arrRef != NULL );
- if( count <= GetSize() && _arrRef->GetReferenceCount() == 1 ) {
- return _arrRef->SetCount( count );
- } else {
- WArrayReference<T> * newRef = _arrRef->MakeCopy( count );
- _arrRef->Unreference();
- _arrRef = newRef;
- return TRUE;
- }
- }
-
- template<class T> WInt WArray<T>::GetCount() const {
- WASSERT( _arrRef != NULL );
- return _arrRef->GetCount();
- }
-
- template<class T> WInt WArray<T>::GetRealCount() const {
- return GetSize();
- }
-
- template<class T> WInt WArray<T>::GetSize() const {
- WASSERT( _arrRef != NULL );
- return _arrRef->GetRealCount();
- }
-
- template<class T> const T & WArray<T>::operator[]( int index ) const {
- WASSERTEX( _arrRef && index < _arrRef->GetCount(), "Array index out of bounds" );
- if( !_arrRef || index < 0 || index >= _arrRef->GetCount() ){
- return GetOutOfBoundsValue();
- }
- return _arrRef->GetData()[index];
- }
-
- template<class T> T & WArray<T>::operator[]( int index ){
- WASSERTEX( _arrRef && index < _arrRef->GetCount(), "Array index out of bounds" );
- if( !_arrRef || index < 0 || index >= _arrRef->GetCount() ){
- return GetDummyValue();
- }
- WArrayReference<T> * oldArrRef = _arrRef;
- if( _arrRef->GetReferenceCount() > 1 ){
- _arrRef = _arrRef->MakeCopy();
- oldArrRef->Unreference();
- }
- return _arrRef->GetData()[index];
- }
-
- template<class T> WArray<T>::operator const T&() const {
- WASSERTEX( _arrRef && _arrRef->GetCount() > 0, "Empty array" );
- if( !_arrRef || _arrRef->GetCount() == 0 ){
- return GetOutOfBoundsValue();
- }
- return _arrRef->GetData()[0];
- }
-
- template<class T> WArray<T>::operator T&(){
- WASSERTEX( _arrRef && _arrRef->GetCount() > 0, "Empty array" );
- if( !_arrRef || _arrRef->GetCount() == 0 ){
- return GetDummyValue();
- }
- WArrayReference<T> * oldArrRef = _arrRef;
- if( _arrRef->GetReferenceCount() > 1 ) {
- _arrRef = _arrRef->MakeCopy();
- oldArrRef->Unreference();
- }
- return _arrRef->GetData()[0];
- }
-
- template<class T> WArray<T> & WArray<T>::operator=( const T & t ){
- if( _arrRef ) _arrRef->Unreference();
- _arrRef = WArrayReference<T>::Allocate( 1 );
- if( _arrRef ) _arrRef->GetData()[0] = t;
- return *this;
- }
-
- template<class T> WArray<T> & WArray<T>::operator=( const WArray<T> & array ){
- if( this != &array ){
- WArrayReference<T> *old = _arrRef;
- _arrRef = array._arrRef;
- if( _arrRef) _arrRef->Reference();
- if( old ) old->Unreference();
- }
- return *this;
- }
-
- template<class T> T* WArray<T>::Lock( WInt count ){
- WASSERT( _arrRef );
- if( count < 0 ){
- count = GetCount();
- }
- if( count == 0 ){
- count = 1;
- }
- SetCount( count );
- WASSERT( _arrRef->GetReferenceCount() == 1 );
- WASSERT( _arrRef->GetData() != NULL );
- return _arrRef->GetData();
- }
-
- template<class T> void WArray<T>::Unlock(){
- WASSERT( _arrRef );
- // nothing to do...
- }
-
- typedef int WCMDEF (*WArraySysCompRtn)( const void *, const void * );
-
- extern int WArrayCompare( const void *, const void * );
- extern WArraySysCompRtn WArrayCompareRoutine;
- extern void WArrayAcquire();
- extern void WArrayRelease();
-
- template<class T>
- class WCMCLASS WSortableArray : public WArray<T> {
-
- public:
-
- typedef int WCMDEF (*WArrayCompareRoutine)( const T *, const T * );
-
- public:
-
- /**********************************************************
- * Constructors and Destructors
- *********************************************************/
-
- WSortableArray();
- WSortableArray( const T & t );
- WSortableArray( const WArray & array );
-
- ~WSortableArray();
-
- /**********************************************************
- * Methods
- *********************************************************/
-
- // Sort
- //
- // Sorts the array using qsort. First locks it, then sorts.
- // If no sort function is provided, sorts in ascending
- // order using '<' and '==' operators.
-
- void Sort( WArrayCompareRoutine routine=NULL );
-
- static int DefaultCompare( const T *, const T * );
- };
-
- template<class T> WSortableArray<T>::WSortableArray() : WArray() {
- }
-
- template<class T> WSortableArray<T>::WSortableArray( const T & t )
- : WArray( t ) {
- }
-
- template<class T> WSortableArray<T>::WSortableArray( const WArray & array )
- : WArray( array ) {
- }
-
- template<class T> WSortableArray<T>::~WSortableArray() {
- }
-
- template<class T> static WSortableArray<T>::DefaultCompare( const T *l, const T *r ){
- if( *l < *r ){
- return -1;
- } else if( *l == *r ){
- return 0;
- } else {
- return 1;
- }
- }
-
- template<class T> void WSortableArray<T>::Sort( WArrayCompareRoutine routine ){
- int count = GetCount();
- if( !_arrRef || count == 0 ) return;
- if( !routine ) routine = DefaultCompare;
- WArrayAcquire();
- T *data = Lock();
- WArrayCompareRoutine = (WArraySysCompRtn) routine;
- qsort( data, count, sizeof( T ), WArrayCompare );
- Unlock();
- WArrayRelease();
- }
-
- //
- // Standard array types
- //
-
- extern template WArrayReference<WInt>;
- extern template WArray<WInt>;
- typedef WArray<WInt> WIntArray;
-
- extern template WArrayReference<WULong>;
- extern template WArray<WULong>;
- typedef WArray<WULong> WULongArray;
-
- extern template WArrayReference<WLong>;
- extern template WArray<WLong>;
- typedef WArray<WLong> WLongArray;
-
- extern template WArrayReference<WBool>;
- extern template WArray<WBool>;
- typedef WArray<WBool> WBoolArray;
-
- #if defined( _UNINCLUDE_NEW )
- #undef new
- #undef delete
- #undef WNew
- #undef WDelete
- #endif
-
- #ifndef _WNO_PRAGMA_PUSH
- #pragma enum pop;
- #pragma pack(pop);
- #endif
-
- #endif // _WARRAY_HPP_INCLUDED
-